<script lang="ts" setup>
import useLoading from '@/hooks/loading'
import { TitleMap } from '@/config/constants'
import request from '@/utils/request'
import { handleTree } from '@/utils'
import { set } from '@vueuse/core'

interface EditProps {
  modelForm: any
  editVisible: boolean
  createData: any
  updateData: any
  title?: string
  dialogStatus: string
  setEditVisible: any
}

const props = withDefaults(defineProps<EditProps>(), {
  editVisible: false,
  modelForm: {
    title: '',
    content: '',
  },
  dialogStatus: 'create',
  createData: () => {},
  updateData: () => {},
  setEditVisible: () => {},
})
const { modelForm } = toRefs(props)
const { loading, setLoading } = useLoading()
const menuExpand = ref(false)
const menuNodeAll = ref(false)
const checkedKeys = ref([])
const menuList = ref<any>([])
const checkStrictly = ref(false)
const menuRef = ref<any>(null)
const formRef = ref<any>(null)

// 获取列表
const getMenuList = () => {
  request({
    url: '/menu',
  }).then((res) => {
    Array.isArray(res.rows) && (menuList.value = handleTree(res?.rows))
  })
}

getMenuList()

const handleClose = () => {
  props.setEditVisible()
  formRef.value!.resetFields()
  set(checkedKeys, [])
}

// 树权限（展开/折叠）
const handleCheckedTreeExpand = (expanded: any) => {
  menuRef.value.expandAll(!!expanded)
}

// 树权限（全选/全不选）
const handleCheckedTreeNodeAll = (value: any) => {
  menuRef.value.checkAll(value)
}

// 树权限（父子联动）
const handleCheckedTreeConnect = (value: any) => {
  checkStrictly.value = value
}

// 所有菜单节点数据
const getMenuAllCheckedIds = () => {
  let checkedIds = []
  // 目前被选中的菜单节点
  const checkedKeys = menuRef.value.getCheckedNodes()
  // 半选中的菜单节点
  const halfCheckedKeys = menuRef.value.getHalfCheckedNodes()
  checkedKeys.unshift(...halfCheckedKeys)

  if (checkedKeys.length) {
    checkedIds = checkedKeys.map((item: any) => item?.id)
  }

  return checkedIds
}

// 提交前进行业务处理
const handleModelForm = (modelForm: any, menuIds: any) => {
  modelForm.value.menuIds = menuIds
  modelForm.value.menus = unref(menuList.value.filter((m: any) => menuIds.includes(m.id)))
  // modelForm.value.menus.forEach((m: any) => (m.roleId = modelForm.value.id))
  // modelForm.value.menus = menuIds.map((item: any) => ({ role_id: modelForm.value.id, id: item, appId: 1, cityId: 2 }))
  console.log('modelForm.value.menus', modelForm.value.menus)
  // debugger

  return modelForm
}

// 发布
const handleSubmit = () => {
  formRef
    .value!.validate((valid: any) => {
      if (valid) return

      const menuIds = getMenuAllCheckedIds()
      // modelForm.value.menus = menuIds.length ? menuIds.map((item: any) => ({ roleId: modelForm.value.id, id: item, appId: 1, cityId: 2 })) : []
      const data = unref(handleModelForm(modelForm, menuIds))
      // const data = unref(modelForm)
      // data.menus = [
      //   { id: 2, roleId: data.id, moduleId: 2, component: '/articles/blog/list', parentId: 1, href: '/articles/blog/list', title: '文章列表' },
      //   { id: 3, roleId: data.id, moduleId: 3, component: '/articles/blog/list2', parentId: 2, href: '/articles/blog/list2', title: '文章列表2' },
      // ]
      // data.menus = [{ id: 2, moduleId: 2, roleId: data.id, createTime: '2022-11-06 16:35:00', updateTime: '2022-11-06 16:35:00', code: '', title: '文章列表', parentId: 1, order: null, status: 1, component: '/articles/blog/list', path: '', blank: null, hidden: null, href: '/articles/blog/list', iconName: 'icon-file', target: null, cityId: null }]

      data.status = data.status ? +data.status : 0
      data.order = data.order ? +data.order : 0
      props.dialogStatus === 'create' ? props.createData(data) : props.updateData(data)

      handleClose()
    })
    .catch((error: any) => {
      console.log('error', error)
    })
    .finally(() => {
      setLoading(false)
    })
}

// 修改时标签选中
watch(
  () => props.modelForm.menus,
  (val: any) => {
    if (!val) {
      return
    }

    set(
      checkedKeys,
      val.map((item: any) => item.id)
    )
  }
)

const visible = ref(false)
watch(
  () => props.editVisible,
  (show) => {
    visible.value = show
  }
)

onMounted(() => {
  modelForm.value.menuCheckStrictly = true
})
</script>
<template>
  <a-modal v-model:visible="visible" @ok="handleSubmit" @cancel="handleClose" draggable :width="600" :loading="loading">
    <template #title>{{ TitleMap[dialogStatus] }}</template>
    <a-form ref="formRef" :model="modelForm" auto-label-width>
      <a-form-item field="id" hidden>
        <input type="hidden" name="id" :value="modelForm.id" />
      </a-form-item>

      <a-form-item label="角色名称" field="name">
        <a-input v-model.trim="modelForm.name" placeholder="请输入角色名称" />
      </a-form-item>
      <a-form-item label="角色顺序" field="order">
        <a-input v-model.trim="modelForm.order" placeholder="请输入角色顺序" />
      </a-form-item>
      <a-form-item label="状态" field="status">
        <a-radio-group v-model="modelForm.status">
          <a-radio :value="1">正常</a-radio>
          <a-radio :value="2">禁用</a-radio>
        </a-radio-group>
      </a-form-item>
      <a-form-item label="菜单权限" field="menu">
        <a-space direction="vertical">
          <a-space size="medium">
            <a-checkbox v-model="menuExpand" @change="handleCheckedTreeExpand">{{ menuExpand ? '展开' : '折叠' }}</a-checkbox>
            <a-checkbox v-model="menuNodeAll" @change="handleCheckedTreeNodeAll">{{ !menuNodeAll ? '全选' : '反选' }}</a-checkbox>
            <a-checkbox v-model="modelForm.menuCheckStrictly" @change="handleCheckedTreeConnect">父子联动</a-checkbox>
          </a-space>
          <a-tree
            class="tree-border"
            ref="menuRef"
            :show-line="true"
            :data="menuList"
            :field-names="{
              key: 'id',
            }"
            :checkable="true"
            v-model:checked-keys="checkedKeys"
            :check-strictly="checkStrictly"
        /></a-space>
      </a-form-item>
      <a-form-item label="备注" field="remark">
        <a-textarea v-model="modelForm.remark" :row="4" :max-length="100" allow-clear show-word-limit auto-size />
      </a-form-item>
    </a-form>
  </a-modal>
</template>
<style lang="scss">
.tree-border {
  width: 480px;
  padding: 3px 10px;
  border: 1px solid #e5e6e7;
  background: #fff none;
  border-radius: 4px;
}
</style>
